package com.xiongwei.io;

import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Java的IO标准库使用Filter模式为InputStream和OutputStream增加功能:
 *  可以把一个InputStream和任意个FilterInputStream组合
 *  可以把一个OutputStream和任意个FilterOutputStream组合
 *
 * Filter模式可以在运行期动态增加功能(又称装饰者模式Decorator)
 *
 * 提供来源的InputStream: FileInputStream, ServletInputStream, Socket.getInputStream...
 * 提供功能的InputStream: BufferedInputStream, DigestInputStream, CipherInputStream...
 *
 *
 * @author XiongWei
 * @date 2021/1/8
 */
public class FilterModeUse {

    public static void main(String[] args) {
        try(CountInputStream is = new CountInputStream(new ByteArrayInputStream("filterMode".getBytes()))) {
            int n;
            while ((n = is.read()) != -1) {
                System.out.println((char) n);
            }
            System.out.println("total read " + is.getCount() + "bytes.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 实现对输入字节进行计数的装饰输入流
 */
class CountInputStream extends FilterInputStream {

    private int count = 0;

    CountInputStream(InputStream is) {
        super(is);
    }

    @Override
    public int read() throws IOException {
        int n = in.read();
        if (n != -1) {
            this.count++;
        }
        return n;
    }

    @Override
    public int read(byte[] bb, int offset, int len) throws IOException{
        int n = in.read(bb, offset, len);
        if (n != -1) {
            this.count += n;
        }
        return n;
    }

    public int getCount() {
        return this.count;
    }

}
